package query_understanding.query_understand.tree_generator;

import algorithm.config.HumanLanguage;
import algorithm.nlp.corenlp.QueryAnnotator;
import algorithm.nlp.corenlp.TextAnnotator;
import edu.stanford.nlp.ling.CoreAnnotations;
import edu.stanford.nlp.util.CoreMap;
import org.springframework.stereotype.Component;
import query_understanding.query_understand.tree_progress.DocumentQueryProgress;
import query_understanding.query_understand.tree_progress.EntityQueryProgress;
import semantic_compute.entity_linking.yago_linker.YagoQueryEntityLinker;
import semantic_compute.relation_extraction.yago_matcher.YagoRelationMatcher;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by julianzliu on 4/22/2017.
 */

@Component
public class QueryTreeGenerator {

    /*
    控制器：
       查询树生成
       保存实例变量
     */


    public DocumentQueryProgress progress;

    public QueryAnnotator textAnnotator;
    public YagoQueryEntityLinker entityLinker;
    public YagoRelationMatcher yagoRelationMatcher;


    //@Inject
    public QueryTreeGenerator(){
        this.textAnnotator = new QueryAnnotator( );
        this.entityLinker = new YagoQueryEntityLinker();
        this.yagoRelationMatcher = new YagoRelationMatcher();
    }



    public DocumentQueryProgress parseQuery(String query){

        /*
        Ambiverse 在没有句号的情况下处理异常
         */
        query += " .";

        this.progress = new DocumentQueryProgress();
        this.progress.originalWholeQuery = query;

        /*
        0） 文档级别预处理
         */
        preProcess( this.progress );


        /*
        1）处理文档中的每个句子
         */
        processAllSentences();


        return this.progress;
    }





    public void preProcess(DocumentQueryProgress progress){

        QueryPreprocessor preprocessor = new QueryPreprocessor( progress );
        //preprocessor.getEntityLinking( new YagoQueryEntityLinker() );
        //preprocessor.getDenpendencyTrees( new TextAnnotator(HumanLanguage.ENGLISH) );

        //preprocessor.getDenpendencyTrees( textAnnotator );
        //preprocessor.alignEntityWithTreeNode();
        //preprocessor.printAlignResult();

        preprocessor.process( textAnnotator );
    }


    public void processAllSentences(){
        /*
        生成每个句子的候选  查询树集合
         */
        List<CoreMap> sentences = this.progress.document.get(CoreAnnotations.SentencesAnnotation.class);
        for(CoreMap sentence:sentences){
            System.out.println("\n\n\n\n----------------------------------------------- sentence ---------------------------------------------->");
            System.out.println(sentence);
            genSentenceCandicateQueryTreeSet(sentence);
            System.out.println("<--------------------------------------------------------------------------------------------------------\n\n\n\n");
        }
    }


    public void genSentenceCandicateQueryTreeSet(CoreMap sentence){
        EntityQueryProgress entityProgress = new EntityQueryProgress();
        entityProgress.sentence = sentence;
        entityProgress.originalQuery = sentence.toString();
        //entityProgress.entityTokenMap = this.progress.sentEntityTokenMap.get( sentence );
        entityProgress.addEntityTokenMap( this.progress.sentEntityTokenMap.get( sentence ) );
        entityProgress.addConceptTokenMap( this.progress.sentConceptTokenMap.get(sentence) );

        this.progress.entityQueryProgressList.add( entityProgress );

        // 0) 生成一棵空树，初始化信息，过滤停用词等
        initializeQueryTree( entityProgress );

        // 1) Topic Entity
        selectTopicEntity( entityProgress );

        // 2) identify Corechain
        identifyCoreChain( entityProgress );

        // 3) extraWords
        extendExtraWords( entityProgress );

    }


    /*****************************************************************************************
     *
     *  以下是针对每个  句子 or 实体查询的子过程
     *
     ****************************************************************************************/


    public void initializeQueryTree(EntityQueryProgress entityQueryProgress){
        System.out.println("\n\n\n\n\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        EntityTreeInitializer treeInitializer = new EntityTreeInitializer(progress, entityQueryProgress);
        treeInitializer.genInitialTree();
        entityQueryProgress.deepFirstTraversal( entityQueryProgress.initTree );
        System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n\n\n\n");
    }


    /*********************************
     *
     * @param entityQueryProgress
     */
    public void selectTopicEntity(EntityQueryProgress entityQueryProgress){
        System.out.println("\n\n\n\n\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        System.out.println("[selectTopicEntity]");
        TopicEntitySelector topicEntitySelector = new TopicEntitySelector(progress, entityQueryProgress);
        topicEntitySelector.selectTopicEntity();
        entityQueryProgress.printAllTress();
        System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n\n\n\n");
    }

    /***********************************
     *
     * @param entityQueryProgress
     */
    public void identifyCoreChain(EntityQueryProgress entityQueryProgress){
        System.out.println("\n\n\n\n\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        System.out.println("[identifyCoreChain]");
        CoreChainIdentifier chainIdentifier = new CoreChainIdentifier(progress, entityQueryProgress);
        chainIdentifier.setYagoRelationMatcher( this.yagoRelationMatcher );
        chainIdentifier.identifyCoreReferenceChain();

        entityQueryProgress.printAllTress();

        System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n\n\n\n");

    }


    public void extendExtraWords(EntityQueryProgress entityQueryProgress){
        System.out.println("\n\n\n\n\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        System.out.println("[extendExtraWords]");
        ExtraWordExtender extraWordExtender = new ExtraWordExtender(progress, entityQueryProgress);
        extraWordExtender.extendExtraWords();

        entityQueryProgress.printAllTress();

        System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n\n\n\n");
    }







    /********************************************************************
     *
     */
    public static void main(String[] args){

        String[] querys = {"wife of Obama", "city where Obama was born.","Obama's brother who voted Trump.","University where Obama's wife graduated."};
        List<String> querysList = new ArrayList<>( Arrays.asList(querys) );

        String new_query = "";
        if(args.length > 0){

            for(String arg:args){
                new_query += " " + arg;
            }
            querysList.add( new_query);
        }

        List<String> sinlgeQueryList = new ArrayList<>();
        sinlgeQueryList.add( new_query );
        //sinlgeQueryList.add("Who married Obama?" );
        //sinlgeQueryList.add("university where wife of Barack Obama graduated.");
        //sinlgeQueryList.add("Obama's borther who voted Trump.");
        test_multiple_query( sinlgeQueryList );
    }


    public static void test_multiple_query(List<String> querysList){
        QueryTreeGenerator generator = new QueryTreeGenerator();
        for(String query:querysList){
            System.out.println("\n\n\n\n\n\n\n\n");
            System.out.println("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS");

            generator.parseQuery( query );

            try{

            }
            catch (Exception e){
                System.err.println(e.getMessage());
            }
            System.out.println("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE");
            System.out.println("\n\n\n\n\n\n\n\n");
        }
    }
}
